package north

import (
	"fmt"
	"iot-base/common/cache"
	"iot-base/common/config"
	"iot-base/common/ctrltype"
	"iot-base/common/event"
	"iot-base/common/eventtype"
	"iot-base/common/logger"
	"iot-base/common/maintain"
	"iot-base/common/mqtt"
	"iot-base/common/property"
	"iot-base/common/types"
	"time"
)

const DBError = -330001

var dataChan chan property.ReportData
var alarmChan chan *eventtype.Alarm
var eventChan chan *eventtype.Event
var recordChan chan types.RecordData

//var eventChan chan *eventtype.Event

func init() {
	dataChan = make(chan property.ReportData)
	property.SetDataChan(dataChan)
	alarmChan = make(chan *eventtype.Alarm)
	event.SetAlarmChan(alarmChan)
	eventChan = make(chan *eventtype.Event)
	event.SetEventChan(eventChan)
	recordChan = make(chan types.RecordData)
}

//var dataChannel chan interface{}
var client mqtt.IOTMQTTBroker

//InitDataPicker 初始化picker
func InitDataPicker() {
	client = mqtt.CreateMQTTClient(config.MQTTOption.Addr, config.MQTTOption.UN, config.MQTTOption.PWD, true,
		config.SelfOption.ID)
	client.RegisterTopic(config.GetEdgeTopic()+"sync/alarms/"+config.SelfOption.ID, handleSyncAlarms, nil)

	client.RegisterTopic(config.GetEdgeTopic()+"remoteCtrl/"+config.SelfOption.ID, handleCtrl, &ctrltype.CtrlCmd{})
	client.RegisterTopic(config.GetEdgeTopic()+"upgrade/all", handleUpgrade, &maintain.UpgradeCmd{})
	client.RegisterTopic(config.GetEdgeTopic()+"upgrade/"+config.SelfOption.ID, handleUpgrade, &maintain.UpgradeCmd{})

	//client.RegisterTopic(config.GetEdgeTopic()+"cmd/"+config.SelfOption.ID, handCmd, &ctrltype.CtrlCmd{})
	go thrd(dataChan)
}

var registerSucc bool
var istimeout bool

func register(cmdtype string, topic string) {
	cmd := mqtt.Cmd{
		CmdType: cmdtype,
		Body:    config.SelfOption.ID,
	}
	//fmt.Println("3333register---rrrr--------", cmdtype)
	//logger.Log.Sugar().Infow("send hb/register-------------------------", "type", cmdtype)
	client.SendCmd(&cmd, config.GetCloudTopic()+topic+"/"+config.SelfOption.ID, 5, &cache.SvrOption{},
		func(client mqtt.IOTMQTTBroker, pCmdResponse *mqtt.CmdResponse, pCmd *mqtt.Cmd) {
			istimeout = false
			if pCmdResponse != nil {
				if pCmdResponse.Code != 0 {
					registerSucc = false
					logger.Log.Sugar().Errorw("get error -------------!!!!!", "error", pCmdResponse.Error, "code",
						pCmdResponse.Code)
				} else {
					registerSucc = true
					//logger.Log.Sugar().Infow("register succ-------------!!!!!")
					cache.SetLastAliveTime(config.SelfOption.ID, time.Now().Unix())
					if pOption, ok := pCmdResponse.Body.(*cache.SvrOption); ok {
						cache.SetSvrOption(*pOption)
						logger.SLog.Info("register -----------ok--and option:", *pOption)

					}
					if cmdtype == "register" {
						states, err := cache.GetAllThingState()
						if states != nil && err == nil {
							cmd := mqtt.Cmd{}
							cmd.CmdType = "states"
							cmd.Body = states
							fmt.Println("---------send states", states)
							client.SendCmd(&cmd, config.GetCloudTopic()+"state/"+config.SelfOption.ID, 0, nil, nil, nil)
						}
					}
					//fmt.Println("register---------ok")

				}
			}
			//fmt.Println("register&&&&&&&&&&&&&&&&&& ok")
		}, func(client mqtt.IOTMQTTBroker, pCmd *mqtt.Cmd) {
			registerSucc = false
			istimeout = true
			fmt.Println("register&&&&&&&&&&&&&&&&&& timeout")
		})
}

func thrd(dataChan chan property.ReportData) {
	timer := time.NewTimer(time.Duration(config.MQTTOption.HTInterval) * time.Second)

	register("register", "register")
	for {
		//fmt.Println("runing----------------------")

		select {
		//timer.Reset
		case data := <-dataChan:
			if registerSucc {
				//fmt.Println("data----------------------------------", data.Data)
				cmd := mqtt.Cmd{}
				cmd.CmdType = "data"
				cmd.Body = data.Data
				client.SendCmd(&cmd, config.GetCloudTopic()+"data/"+config.SelfOption.ID, 0, nil, nil, nil)
			}
		case pAlarm := <-alarmChan:
			if pAlarm != nil {
				cmd := mqtt.Cmd{}
				cmd.CmdType = "alarm"
				cmd.Body = pAlarm
				client.SendCmd(&cmd, config.GetCloudTopic()+"alarm/"+config.SelfOption.ID, 0, nil, nil, nil)
			}
		case pEvent := <-eventChan:
			if pEvent != nil {
				cmd := mqtt.Cmd{}
				cmd.CmdType = "event"
				cmd.Body = pEvent
				client.SendCmd(&cmd, config.GetCloudTopic()+"event/"+config.SelfOption.ID, 0, nil, nil, nil)
			}
		case data := <-recordChan:
			cmd := mqtt.Cmd{}
			cmd.CmdType = "record"
			cmd.Body = data
			client.SendCmd(&cmd, config.GetCloudTopic()+"record/"+config.SelfOption.ID, 0, nil, nil, nil)
		case <-timer.C:
			//fmt.Print("begin--------------register or hb--------------")
			if registerSucc {
				register("hb", "hb")

			} else {
				register("register", "register")
			}
			if registerSucc || istimeout {
				timer.Reset(time.Duration(config.MQTTOption.HTInterval) * time.Second)
			} else {
				timer.Reset(time.Duration(120) * time.Second)
				//fmt.Println("long time-------------------------")
			}

		}
	}
}

func SendRecord(data types.RecordData) {
	recordChan <- data
}
